home *** CD-ROM | disk | FTP | other *** search
- PAGE ,132
- ;----------------------------------------------------------
- ; ATOF -- version for use with assembly language programs
- ;
- ; Copyright Bob Kline 1988
- ;
- ; Purpose:
- ; Convert ASCII string to floating point value
- ;
- ; Input:
- ; SI points to start of string
- ;
- ; Output:
- ; DX:AX contain 4-byte real
- ;
- ; Other registers used:
- ; Values destroyed in BP, SI, DI, BX, CX
- ;
- ; Procedures:
- ; FDECTOBIN
- ;----------------------------------------------------------
- PUBLIC ATOF
- EXTRN FDECTOBIN:NEAR
-
- .MODEL SMALL
-
- INDEX EQU SI
- CHARACTER EQU BYTE PTR [SI]
- DECIMALPLACES EQU DI
- ROUNDINGFLAG EQU BP
-
- .CODE
-
- ATOF PROC
-
- ; initialize flags and counters
- XOR DECIMALPLACES,DECIMALPLACES
- XOR ROUNDINGFLAG,ROUNDINGFLAG
-
- ; skip past leading spaces
- L2: CMP CHARACTER,' '
- JNE L1
- INC INDEX
- JMP L2
-
- ; save sign of mantissa
- L1: XOR AX,AX
- CMP CHARACTER,'+'
- JE L0
- CMP CHARACTER,'-'
- JNE L3
- INC AX
- L0: INC INDEX
- L3: PUSH AX
-
- ; zero out mantissa and check for digit in string
- XOR AX,AX
- XOR DX,DX
- MOV CX,10
- JMP SHORT L4
-
- ; if mantissa not full use the digit
- L9: TEST DX,0F000h
- JNZ L5
- PUSH AX
- XCHG DX,AX
- MUL CX ; 10
- MOV BX,AX
- POP AX
- MUL CX
- ADD DX,BX
- MOV BL,CHARACTER
- AND BX,0Fh
- ADD AX,BX
- JNC L6
- INC DX
- JMP SHORT L6
-
- ; mantissa full: round up if necessary
- L5: OR ROUNDINGFLAG,ROUNDINGFLAG
- JNZ L7
- INC ROUNDINGFLAG
- CMP CHARACTER,'5'
- JB L7
- INC AX
- JNC L7
- INC DX
- L7: DEC DECIMALPLACES
-
- ; check to see whether the next char is a digit and loop back if it is
- L6: INC INDEX
- L4: CMP CHARACTER,'0'
- JB L8
- CMP CHARACTER,'9'
- JNA L9
-
- ; take care of digits after decimal point
- L8: CMP CHARACTER,'.'
- JNE L10
- INC INDEX
- MOV CX,10
- JMP SHORT L11
-
- ; if mantissa not full use the digit
- L15: TEST DX,0F000h
- JNZ L12
- PUSH AX
- XCHG DX,AX
- MUL CX ; 10
- MOV BX,AX
- POP AX
- MUL CX
- ADD DX,BX
- MOV BL,CHARACTER
- AND BX,0Fh
- ADD AX,BX
- JNC L13
- INC DX
- L13: INC DECIMALPLACES
- JMP SHORT L14
-
- ; mantissa full -- round up if necessary
- L12: OR ROUNDINGFLAG,ROUNDINGFLAG
- JNZ L14
- INC ROUNDINGFLAG
- CMP CHARACTER,'5'
- JB L14
- INC AX
- JNC L14
- INC DX
-
- ; check to see whether next character is a digit and loop back if it is
- L14: INC INDEX
- L11: CMP CHARACTER,'0'
- JB L10
- CMP CHARACTER,'9'
- JNA L15
-
- ; put lower half of mantissa on stack so we can use AX to calculate
- ; the exponent
- L10: PUSH AX
- XOR AX,AX
-
- ; check for an exponent
- CMP CHARACTER,'e'
- JE L16
- CMP CHARACTER,'E'
- JNE L17
-
- ; save the exponent's sign
- L16: XOR CX,CX
- INC INDEX
- CMP CHARACTER,'+'
- JE L18
- CMP CHARACTER,'-'
- JNE L19
- INC CX
- L18: INC INDEX
- L19: PUSH CX
-
- ; calculate exponent
- MOV CL,10
- JMP SHORT L20
- L22: MUL CL
- AND CHARACTER,0Fh
- ADD AL,CHARACTER
- INC INDEX
-
- ; see if character is another digit
- L20: CMP CHARACTER,'0'
- JB L21
- CMP CHARACTER,'9'
- JNA L22
-
- ; get the sign for the exponent back from the stack, negating the
- ; exponent if the sign is set
- L21: POP CX
- OR CX,CX
- JZ L17
- NEG AX
-
- ; get the exponent into BX where it belongs, and adjust it for the
- ; number of decimal places we found in the string
- L17: MOV BX,AX
- SUB BX,DECIMALPLACES
-
- ; get the low word of the mantissa back into AX
- POP AX
-
- ; get the sign back off the stack (remember, we stuck it there at
- ; the very beginning of the procedure)
- POP CX
-
- ; if the mantissa is zero, make sure the sign bit is zero
- OR AX,AX
- JNZ NOT_0
- OR DX,DX
- JNZ NOT_0
- XOR CX,CX
- NOT_0:
-
- ; call fdectobin to convert the decimal components into
- ; a 4-byte real
- CALL FDECTOBIN
- RET
-
- ATOF ENDP
-
- END